package main

import (
	"fmt"
	"strconv"
	"time"
)

/*
   缓冲通道
   缓冲通道就是指一个通道，带有一个缓冲区。发送到一个缓冲通道只有在缓冲区满时才被阻塞。类似地，从缓冲通道接收的信息只有在缓冲区为空时才会被阻塞。

   可以通过将额外的容量参数传递给make函数来创建缓冲通道，该函数指定缓冲区的大小。
   ch := make(chan type, capacity)

    非缓存通道：make(chan T)
    缓存通道：make(chan T ,size)
        缓存通道，理解为是队列：

    非缓存，发送还是接受，都是阻塞的
    缓存通道,缓存区的数据满了，才会阻塞状态。。

   对无缓冲 channel 类型的发送与接收操作，一定要放在两个不同的 Goroutine 中进行，否则会导致 deadlock
*/
func main() {

	// 非缓存的通道
	ch01 := make(chan int)
	fmt.Println(len(ch01), cap(ch01)) //0 0

	//缓存的通道，缓存区大小是5
	ch02 := make(chan int, 5)
	fmt.Println(len(ch02), cap(ch02)) //0 5

	// 缓存的通道，缓存区大小是4
	ch03 := make(chan string, 4)

	go sendData(ch03)

	for {
		time.Sleep(1 * time.Second)
		v, ok := <-ch03
		if !ok {
			fmt.Println("buf 读完了，，", ok)
			break
		}
		fmt.Println("\t读取的数据是：", v)
	}
	fmt.Println("main...over...")

}

func sendData(ch chan string) {
	for i := 0; i < 10; i++ {
		ch <- "数据" + strconv.Itoa(i)
		fmt.Println("子goroutine，写出第", i, "个数据")
	}
	close(ch)
}
